package ee.nlp.evn.tools;

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.regex.*;
import java.util.regex.Pattern;

import ee.nlp.evn.entities.*;

public class Analyser {

	private static String dataType;

	private static String removeStrongTags(String s) {
		String result = s;
		String buf = s;
		String bop = "<span class=\"strong\">";
		String eop = "</span>";
		Pattern pattern = Pattern.compile(bop);
		boolean flag;
		do {
			flag = false;
			Matcher m = pattern.matcher(buf);
			if (m.find()) {
				String[] ss = buf.split(bop);
				result = ss[0];
				int l = ss.length;
				int i = 1;
				while (l > 1) {
					result = result + ss[i].replaceFirst(eop, "");
					l--;
					i++;
					flag = true;
				}
			}
			buf = result;
		} while (flag);
		return result;
	}

	private static String removeBrTag(String s) {
		String result = s.replaceFirst("<br />", "");
		;
		return result;
	}

	public static ArrayList<Annotation> parseTextCorpusAnnotation(
			String textLine) {
		ArrayList<Annotation> result = new ArrayList<Annotation>();
		String bop = "<span class=\"gram\">";
		String eop = "</span>";
		Pattern pattern = Pattern.compile(bop);
		Matcher m = pattern.matcher(textLine);
		if (m.find()) {
			String content = textLine.substring(bop.length(),
					textLine.indexOf(eop)).trim();
			String tkn;
			String tag = "";
			String lvl = "trunk";
			// trunk
			do {
				tkn = Tokenizer.getFirstToken(content);
				content = content.substring(tkn.length()).trim();
				if (!"/".equals(tkn))
					tag += tkn;
				else
					content = content.substring(1);
			} while (!"/".equals(tkn));
			result.add(new Annotation(lvl, tag));
			// morph
			lvl = "morph";
			tag = "";
			do {
				tkn = Tokenizer.getFirstToken(content);
				content = content.substring(tkn.length()).trim();
				if (!"/".equals(tkn) && !"_".equals(tkn)) {
					tag = tkn;
					result.add(new Annotation(lvl, tag));
				} else if ("/".equals(tkn))
					content = content.substring(1);
			} while (!"/".equals(tkn));
		}
		return result;
	}

	public static ArrayList<Annotation> parseKymCorpusAnnotation(String textLine) {
		ArrayList<Annotation> result = new ArrayList<Annotation>();
		String content = textLine.trim();
		String tkn;
		String tag = "";
		String lvl = "trunk";
		// trunk
		do {
			tkn = Tokenizer.getFirstToken(content);
			content = content.substring(tkn.length()).trim();
			if (!"/".equals(tkn))
				tag += tkn;
			else
				content = content.substring(1);
		} while (!"/".equals(tkn));
		result.add(new Annotation(lvl, tag));
		// morph
		lvl = "morph";
		tag = "";
		do {
			tkn = Tokenizer.getFirstToken(content);
			content = content.substring(tkn.length()).trim();
			if (!"/".equals(tkn) && !"_".equals(tkn)) {
				tag = tkn;
				result.add(new Annotation(lvl, tag));
			} else if ("/".equals(tkn))
				content = content.substring(1);
		} while (!"/".equals(tkn));
		return result;
	}

	public static ArrayList<Annotation> parseKysCorpusAnnotation(String textLine) {
		ArrayList<Annotation> result = new ArrayList<Annotation>();
		String content = textLine.trim();
		String tkn;
		String tag = "";
		String lvl = "trunk";
		// trunk
		do {
			tkn = Tokenizer.getFirstToken(content);
			content = content.trim().substring(tkn.length()).trim();
			if (!"/".equals(tkn))
				tag += tkn;
			else
				content = content.substring(1);
		} while (!"/".equals(tkn));
		result.add(new Annotation(lvl, tag));
		// morph
		lvl = "morph";
		tag = "";
		do {
			tkn = Tokenizer.getFirstToken(content);
			content = content.trim().substring(tkn.length()).trim();
			if (!"/".equals(tkn) && !"_".equals(tkn)) {
				tag = tkn;
				result.add(new Annotation(lvl, tag));
			} else if ("/".equals(tkn))
				content = content.substring(1);
		} while (!"/".equals(tkn));
		// semy
		lvl = "semy";
		tag = "";
		do {
			tkn = Tokenizer.getFirstToken(content);
			content = content.trim().substring(tkn.length()).trim();
			if (!tkn.isEmpty()) {
				tag += tkn;
			}
		} while (!tkn.isEmpty());
		if (!tag.isEmpty()) {
			result.add(new Annotation(lvl, tag));
		}
		return result;
	}

	public static Sentence parseCorpusTextLine(String textLine) {
		Sentence result = new Sentence();
		String line = removeStrongTags(textLine);
		line = removeBrTag(line);
		String src = "";
		for (int i = 0; i < 3; i++) {
			String tkn = Tokenizer.getFirstToken(line);
			line = line.substring(tkn.length());
			src += tkn;
		}
		result.setSource(src);
		while (!line.isEmpty()) {
			line = line.trim();
			// System.out.println("--1|"+line);
			String wrd = Tokenizer.getFirstToken(line);
			line = line.substring(wrd.length()).trim();
			// System.out.println("--2|"+wrd+"|"+line);
			Word w = new Word(wrd);
			if (!line.isEmpty() && line.substring(0, 1).equals("<")) {
				// System.out.println("--|"+w.getUsedForm()+"|"+line);
				ArrayList<Annotation> al = parseTextCorpusAnnotation(line);
				w.setTags(al);
				if (!al.isEmpty()) {
					line = line.substring(line.indexOf("</span>")
							+ "</span>".length());
				}
			}
			result.addWord(w);
		}
		return result;
	}

	public static Word parseCorpusKymLine(String textLine) {
		String line = textLine.trim();
		Word result = new Word("");
		if (!line.isEmpty()) {
			line = line.trim();
			// System.out.println("--1|"+line);
			String wrd = Tokenizer.getFirstToken(line);
			line = line.substring(wrd.length()).trim();
			// System.out.println("--2|"+wrd+"|"+line);
			result.setUsedForm(wrd);
			if (!line.isEmpty()) {
				// System.out.println("--|"+w.getUsedForm()+"|"+line);
				ArrayList<Annotation> al = parseKymCorpusAnnotation(line);
				result.setTags(al);
			}
		}
		return result;
	}

	public static Word parseCorpusKysLine(String textLine) {
		String line = textLine.trim();
		Word result = new Word("");
		if (!line.isEmpty()) {
			line = line.trim();
			// System.out.println("--1|"+line);
			String wrd = Tokenizer.getFirstToken(line);
			line = line.substring(wrd.length()).trim();
			// System.out.println("--2|"+wrd+"|"+line);
			result.setUsedForm(wrd);
			if (!line.isEmpty()) {
				// System.out.println("--|"+w.getUsedForm()+"|"+line);
				ArrayList<Annotation> al = parseKysCorpusAnnotation(line);
				result.setTags(al);
			}
		}
		return result;
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		if (args.length != 3) {
			System.err
					.println("usage:\tAnalyser <data_file> <data_type> <result_file>");
			System.exit(0);
		}
		Text collection = new Text();
		collection.setTitle(args[0]);
		dataType = args[1];
		if (dataType.equals("txt")) {
			int sentenceCounter = 0;
			try {
				BufferedReader input = new BufferedReader(new FileReader(
						args[0]));
				Sentence ls;
				for (String line = input.readLine(); line != null; line = input
						.readLine()) {
					line = HTMLEntities.unhtmlentities(line.trim());
					if (!"--".equals(line)) {
						ls = parseCorpusTextLine(line);
						System.out.println(ls.getOutputForm());
						System.out.println(ls.getTagForm());
						System.out.println(line);
						System.out.println();
						if (ls.includesTag("trunk", "istu")) {
							sentenceCounter++;
							collection.addSentence(ls);
						}
					}
				}
				input.close();
				System.out.println("Lauseid kokku: " + sentenceCounter);

			} catch (IOException e) {
				e.printStackTrace();
				System.exit(1);
			}
		}
		if (dataType.equals("t3olp")) {
			int sentenceCounter = 0;
			try {
				File input = new File(args[0]);
				collection = T3olpAjavDocumentLoader.parseFromFile(input,
						"UTF-8");
				sentenceCounter = collection.getSentences().size();
				System.out.println("Lauseid kokku: " + sentenceCounter);

				BufferedWriter o = new BufferedWriter(new FileWriter(args[2]));
				o.write("Lauseid kokku: " + sentenceCounter + "\n");

				HashMap<String, Integer> counter = new HashMap<String, Integer>(); 

				VerbNet vn = new VerbNet();
				for (Sentence lause : collection.getSentences()) {
					for (Sentence ls : lause.getPartials()) {
						for (Word w : ls.getWords()) {
							int variant = 0;
							while (w.includeTag("POS", "V", variant)) {
								variant = w.getCurrentVariant();
								ArrayList<VerbClass> vcl = (ArrayList<VerbClass>) vn
										.getClassesForVerb(w.getTrunk(variant));
								for (VerbClass vc : vcl) {
									Verb verb = vc.getMember(w.getTrunk(variant));
									if (verb == null) {
										System.err.println(w.getTrunk(variant)+" : verb is null in vc: "+vc.toString() );
										System.err.println(ls.getTagForm());
									}
									for (Frame f : vc.getFrames()) {
										int marks = calculateMatch(
												f.getPattern(), ls,
												w.getTrunk(variant));
										if (marks > 0 && !w.includeTag("sem", verb.getWn_idx(), variant)) {
											w.addTag(
													"sem",
													verb.getWn_idx()
															//+ " ["
															//+ String.valueOf(marks)
															//+ "]"
													, variant);
											if (counter.containsKey(verb.getWn_idx())) {
												counter.put(verb.getWn_idx(), new Integer(counter.get(verb.getWn_idx()).intValue()+1));
											} else {
												counter.put(verb.getWn_idx(), new Integer(1));
											}
											
										}
									}
								}
								variant++;
							}
						}
						o.write(ls.getOutputForm() + "\n");
						o.write(ls.getTagForm() + "\n");
					}
					o.write(lause.getOutputForm() + "\n");
					// o.write(ls.getTagForm() + "\n");
					o.write("\n");
				}
				for (String key : counter.keySet()) {
					o.write(key + " : " + String.valueOf(counter.get(key).intValue()) + "\n");
				}
				int mtacnt = 0;
				int dblcnt = 0;
				for (Sentence lause : collection.getSentences()) {
					for (Word w : lause.getWords()) {
						int variant = 0;
						while (w.includeTag("POS", "V", variant) 
								&& w.getTrunk(variant).split("\\+")[0].equals("istu")) {
							if(!(w.includeTag("sem", "istuma_1", variant) || w.includeTag("sem", "istuma_4", variant))) {
								mtacnt++;
							}
							if((w.includeTag("sem", "istuma_1", variant) && w.includeTag("sem", "istuma_4", variant))) {
								dblcnt++;
							}
							variant++;
						}
					}
				}
				o.write("Määramata : " + String.valueOf(mtacnt) + "\n");
				o.write("Topelt : " + String.valueOf(dblcnt) + "\n");
				
				o.close();

			} catch (IOException e) {
				e.printStackTrace();
				System.exit(1);
			} catch (Exception e) {
				e.printStackTrace();
				System.exit(1);
			}
		}
		if (dataType.equals("kym")) {
			int sentenceCounter = 0;
			try {
				BufferedReader input = new BufferedReader(new FileReader(
						args[0]));
				String line;
				do {
					for (line = input.readLine(); line != null; line = input
							.readLine()) {
						line = line.trim();
						if (!(line.equals("") || line.startsWith("#")))
							break;
					}
					if (line != null && line.equals("<s>")) { // start
						Sentence ls = new Sentence();
						for (line = input.readLine(); line != null; line = input
								.readLine()) {
							line = line.trim();
							if (line.equals("</s>"))
								break;
							if (!line.isEmpty()) {
								line = HTMLEntities.unhtmlentities(line);
								ls.addWord(parseCorpusKymLine(line));
							}
						}
						System.out.println(ls.getOutputForm());
						System.out.println(ls.getTagForm());
						System.out.println();
						if (ls.includesTag("trunk", "istu")) {
							sentenceCounter++;
							collection.addSentence(ls);
						}
					}
				} while (line != null);
				input.close();

				BufferedWriter o = new BufferedWriter(new FileWriter(args[2]));
				o.write("Lauseid kokku: " + sentenceCounter + "\n");
				int semcnt = 0;
				VerbNet vn = new VerbNet();
				for (Sentence ls : collection.getSentences()) {
					for (Word w : ls.getWords()) {
						String t1 = w.getUsedForm();
						if (w.includeTag("morph", "V")) {
							ArrayList<VerbClass> vcl = (ArrayList<VerbClass>) vn
									.getClassesForVerb(w.getTrunk());
							for (VerbClass vc : vcl) {
								Verb verb = vc.getMember(w.getTrunk());
								for (Frame f : vc.getFrames()) {
									int marks = calculateMatch(f.getPattern(),
											ls, w.getTrunk());
									if (marks > 0) {
										w.addTag("sem", verb.getWn_idx() + " ["
												+ String.valueOf(marks) + "]");
										semcnt++;
									}
								}
							}
						}
					}

					o.write(ls.getOutputForm() + "\n");
					o.write(ls.getTagForm() + "\n");
					o.write("\n");
				}
				o.write("istuma_1 : " + String.valueOf(semcnt) + "\n");
				o.close();
			} catch (IOException e) {
				e.printStackTrace();
				System.exit(1);
			}
		}
		if (dataType.equals("kys")) {
			int sentenceCounter = 0;
			int breaker = 0;
			try {
				BufferedReader input = new BufferedReader(new FileReader(
						args[0]));
				String line;
				do {
					breaker++;
					for (line = input.readLine(); line != null; line = input
							.readLine()) {
						line = line.trim();
						if (!(line.isEmpty() || line.startsWith("#")
								|| line.startsWith("<p>") || line
									.startsWith("</p>")))
							break;
						breaker++;
					}
					if (line != null && line.equals("<s>")) { // start
						Sentence ls = new Sentence();
						for (line = input.readLine(); line != null; line = input
								.readLine()) {
							line = line.trim();
							if (line.equals("</s>"))
								break;
							if (!line.isEmpty()) {
								String tline = line;
								tline = HTMLEntities.unhtmlentities(tline);
								line = input.readLine();
								if (line != null && !line.isEmpty()) {
									tline = tline + " "
											+ HTMLEntities.unhtmlentities(line);
								}
								ls.addWord(parseCorpusKysLine(tline));
								breaker = 0;
							}
						}
						System.out.println(ls.getOutputForm());
						System.out.println(ls.getTagForm());
						System.out.println();
						if (ls.includesTag("trunk", "istu")) {
							sentenceCounter++;
							collection.addSentence(ls);
						}
						System.out.println(sentenceCounter);
						System.out.println();
					}
				} while (line != null && (breaker < 100));
				input.close();

				System.out.println("Alustan analüüsi ...");
				BufferedWriter o = new BufferedWriter(new FileWriter(args[2]));
				o.write("Lauseid kokku: " + sentenceCounter + "\n");
				int semcnt = 0;
				VerbNet vn = new VerbNet();
				for (Sentence ls : collection.getSentences()) {
					for (Word w : ls.getWords()) {
						String t1 = w.getUsedForm();
						if (w.includeTag("morph", "V")) {
							ArrayList<VerbClass> vcl = (ArrayList<VerbClass>) vn
									.getClassesForVerb(w.getTrunk());
							for (VerbClass vc : vcl) {
								Verb verb = vc.getMember(w.getTrunk());
								for (Frame f : vc.getFrames()) {
									int marks = calculateMatch(f.getPattern(),
											ls, w.getTrunk());
									if (marks > 0) {
										w.addTag("sem", verb.getWn_idx() + " ["
												+ String.valueOf(marks) + "]");
										semcnt++;
									}
								}
							}
						}
					}

					o.write(ls.getOutputForm() + "\n");
					o.write(ls.getTagForm() + "\n");
					o.write("\n");
				}
				o.write("istuma_1 : " + String.valueOf(semcnt) + "\n");
				o.close();
			} catch (IOException e) {
				e.printStackTrace();
				System.exit(1);
			}
		}
	}

	private static int calculateMatch(ee.nlp.evn.entities.Pattern pattern,
			Sentence ls, String trunk) {
		int result = 0;
		int score;
		String m = trunk.split("\\+")[0];
		ArrayList<ArrayList<POS>> M = new ArrayList<ArrayList<POS>>();
		for (OP op : pattern.getOps()) {
			M.add((ArrayList<POS>) op.getWords());
			if (op.getName().equals("Perm")) {
				// TODO: Add permutation generation
			}
			for (ArrayList<POS> L : M) {
				score = 0;
				for (POS pos : L) {
					// POS in focus
					String tag = pos.getTag();
					ArrayList<String> rst = (ArrayList<String>) pos
							.getSynRestrs();
					// Looking for POS in sentence (no order checking)
					boolean found = false;
					for (Word w : ls.getWords()) {
						// matching tag and word
						if (tag.equals("V") && w.includeTag("POS", "V")
								&& w.includeTag("trunk", m)) {
							found = true;
						} else if (tag.equals("NP")
								&& (w.includeTag("POS", "S")
										|| w.includeTag("POS", "H")
										|| w.includeTag("POS", "P"))) {
							found = true;
						} else if (tag.equals("PP.location")
								&& (w.includeTag("POS", "S") 
										|| w.includeTag("POS", "P")
										|| w.includeTag("POS", "D"))) {
							found = true;
						}
						if (found) {
							int lc = 0;
							if (rst != null) {
								for (String synrestr : rst) {
									if (checkSyntaxRestriction(synrestr, w, ls)) {
										lc++;
									} else {
										found = false;
									}
								}
							} else {
								lc++;
							}
							if (found) {
								score += lc;
								break;
							}
						}
					}
					if (!found) {
						score = 0;
						break;
					}
				}
				if (score > result)
					result = score;
			}
		}
		return result;
	}

	private static boolean isImper(Word w) {
        return w.includeTag("morph", "o") || w.includeTag("morph", "ge") || w.includeTag("morph", "gem") || w.includeTag("morph", "gu") || w.includeTag("morph", "tagu");
	}
	
	private static boolean checkSyntaxRestriction(String synrestr, Word w,
			Sentence s) {
		boolean result = false;
		if ("+nom".equals(synrestr)) {
			result = w.includeTag("morph", "n");
		}
		if ("+imper".equals(synrestr)) {
			result = isImper(w);
		}
		if ("-imper".equals(synrestr)) {
			result = !isImper(w);
		}
		if ("-Actor".equals(synrestr)) {
			result = w.includeTag("morph", "n") 
					|| w.includeTag("morph", "me") 
					|| w.includeTag("morph", "te") 
					|| w.includeTag("morph", "sin") 
					|| w.includeTag("morph", "sime") 
					|| w.includeTag("morph", "site");
		}
		if ("+Loc".equals(synrestr)) {
			result = ((w.includeTag("morph", "ad")
					|| w.includeTag("morph", "in")) 
					|| (w.includeTag("morph", "g") && (
							s.after(w).getUsedForm().equals("all")
							|| s.after(w).getUsedForm().equals("asemel")
							|| s.after(w).getUsedForm().equals("ees")
							|| s.after(w).getUsedForm().equals("juures")
							|| s.after(w).getUsedForm().equals("järel")
							|| s.after(w).getUsedForm().equals("keskel")
							|| s.after(w).getUsedForm().equals("kohal")
							|| s.after(w).getUsedForm().equals("kõrval")
							|| s.after(w).getUsedForm().equals("käes")
							|| s.after(w).getUsedForm().equals("küljes")
							|| s.after(w).getUsedForm().equals("ligi")
							|| s.after(w).getUsedForm().equals("ligidal")
							|| s.after(w).getUsedForm().equals("lähedal")
							|| s.after(w).getUsedForm().equals("man")
							|| s.after(w).getUsedForm().equals("najal")
							|| s.after(w).getUsedForm().equals("otsas")
							|| s.after(w).getUsedForm().equals("peal")
							|| s.after(w).getUsedForm().equals("pool")
							|| s.after(w).getUsedForm().equals("sees")
							|| s.after(w).getUsedForm().equals("taga")
							|| s.after(w).getUsedForm().equals("vastas")
							|| s.after(w).getUsedForm().equals("vastu")
							|| s.after(w).getUsedForm().equals("ääres")
							|| s.before(w).getUsedForm().equals("ümber") 
							|| s.after(w).getUsedForm().equals("ümber")))
					|| (w.includeTag("morph", "g") && w.includeTag("morph", "pl") && (
							s.after(w).getUsedForm().equals("hulgas")
							|| s.after(w).getUsedForm().equals("seas")
							|| s.after(w).getUsedForm().equals("vahel")))
					|| (w.includeTag("morph", "p") && (
							s.before(w).getUsedForm().equals("allpool")
							|| s.before(w).getUsedForm().equals("eespool")
							|| s.before(w).getUsedForm().equals("keset")
							|| s.before(w).getUsedForm().equals("kesk")
							|| s.before(w).getUsedForm().equals("pealpool")
							|| s.before(w).getUsedForm().equals("sealpool")
							|| s.before(w).getUsedForm().equals("seespool")
							|| s.before(w).getUsedForm().equals("siinpool")
							|| s.before(w).getUsedForm().equals("tagapool")
							|| s.before(w).getUsedForm().equals("teispool")
							|| (s.before(w).getUsedForm().equals("pool") && s
									.before(s.before(w)).getUsedForm()
									.equals("teisel"))
							|| s.before(w).getUsedForm().equals("vastu")
							|| s.before(w).getUsedForm().equals("väljaspool")
							|| s.before(w).getUsedForm().equals("ülalpool")))
					|| (w.includeTag("morph", "el") && (
							s.after(w).getUsedForm().equals("paremal")
							|| s.after(w).getUsedForm().equals("eespool")
							|| s.after(w).getUsedForm().equals("tagapool")
							|| s.after(w).getUsedForm().equals("allpool")
							|| s.after(w).getUsedForm().equals("pealpool") 
							|| s.after(w).getUsedForm().equals("vasakul"))))
					|| w.getTrunk().equals("all+0")
					|| w.getTrunk().equals("allpool+0")
					|| w.getTrunk().equals("eemal+0")
					|| w.getTrunk().equals("ees+0")
					|| w.getTrunk().equals("eespool+0")
					|| w.getTrunk().equals("juures+0")
					|| w.getTrunk().equals("kaugel+0")
					|| w.getTrunk().equals("kodus+0")
					|| w.getTrunk().equals("kus+0")
					|| w.getTrunk().equals("kusagil+0")
					|| w.getTrunk().equals("kuskil+0")
					|| w.getTrunk().equals("kõikjal+0")
					|| w.getTrunk().equals("kõrval+0")
					|| w.getTrunk().equals("ligi+0")
					|| w.getTrunk().equals("ligidal+0")
					|| w.getTrunk().equals("lähedal+0")
					|| w.getTrunk().equals("mujal+0")
					|| w.getTrunk().equals("paremal+0")
					|| w.getTrunk().equals("seal+0")
					|| w.getTrunk().equals("sealpool+0")
					|| w.getTrunk().equals("siin+0")
					|| w.getTrunk().equals("siinpool+0")
					|| w.getTrunk().equals("siin-seal+0")
					|| w.getTrunk().equals("taamal+0")
					|| w.getTrunk().equals("taga+0")
					|| w.getTrunk().equals("tagapool+0")
					|| w.getTrunk().equals("teisal+0")
					|| w.getTrunk().equals("väljas+0")
					|| w.getTrunk().equals("väljaspool+0")
					|| w.getTrunk().equals("ülal+0")
					|| w.getTrunk().equals("ülalpool+0")
					|| w.getTrunk().equals("üleval+0");
		}
		if ("+Di".equals(synrestr)) {
			result = ((w.includeTag("morph", "all")
					|| w.includeTag("morph", "ill") 
					|| w.includeTag("morph", "adt"))
					|| (w.includeTag("morph", "g") && (
							s.after(w).getUsedForm().equals("peale")
							|| s.after(w).getUsedForm().equals("sisse")
							|| s.after(w).getUsedForm().equals("asemele")
							|| s.after(w).getUsedForm().equals("kohale")
							|| s.after(w).getUsedForm().equals("kõrvale")
							|| s.after(w).getUsedForm().equals("lähedale")
							|| s.after(w).getUsedForm().equals("kätte")
							|| s.after(w).getUsedForm().equals("külge")
							|| s.after(w).getUsedForm().equals("ligi")
							|| s.after(w).getUsedForm().equals("ligidale")
							|| s.after(w).getUsedForm().equals("alla")
							|| s.after(w).getUsedForm().equals("ette")
							|| s.after(w).getUsedForm().equals("taha")
							|| s.after(w).getUsedForm().equals("äärde")
							|| s.after(w).getUsedForm().equals("vastu")
							|| s.after(w).getUsedForm().equals("poole")
							|| s.after(w).getUsedForm().equals("lähedusse")
							|| s.after(w).getUsedForm().equals("lähedale")
							|| s.after(w).getUsedForm().equals("manu")
							|| s.after(w).getUsedForm().equals("üle")
							|| s.after(w).getUsedForm().equals("ümber")
							|| s.after(w).getUsedForm().equals("najale")
							|| s.after(w).getUsedForm().equals("otsa")
							|| s.before(w).getUsedForm().equals("üle")
							|| s.before(w).getUsedForm().equals("ümber") 
							|| s.after(w).getUsedForm().equals("selga")))
					|| (w.includeTag("morph", "p") && (
							s.before(w).getUsedForm().equals("allapoole")
							|| s.before(w).getUsedForm().equals("sissepoole")
							|| s.before(w).getUsedForm().equals("keset")
							|| s.before(w).getUsedForm().equals("kesk")
							|| s.before(w).getUsedForm().equals("pealepoole")
							|| s.before(w).getUsedForm().equals("tahapoole")
							|| s.before(w).getUsedForm().equals("teispoole")
							|| (s.before(w).getUsedForm().equals("poole") && s
									.before(s.before(w)).getUsedForm()
									.equals("teisele"))
							|| s.before(w).getUsedForm().equals("vastu") || s
							.before(w).getUsedForm().equals("ettepoole"))) 
					|| (w.includeTag("morph", "el") && (
							s.after(w).getUsedForm().equals("paremale")
							|| s.after(w).getUsedForm().equals("ettepoole")
							|| s.after(w).getUsedForm().equals("tahapoole")
							|| s.after(w).getUsedForm().equals("teispoole")
							|| s.after(w).getUsedForm().equals("allapoole")
							|| s.after(w).getUsedForm().equals("pealepoole") 
							|| s.after(w).getUsedForm().equals("vasakule"))))
					|| w.getTrunk().equals("maha+0")
					|| w.getTrunk().equals("alla+0")
					|| w.getTrunk().equals("allapoole+0")
					|| w.getTrunk().equals("eemale+0")
					|| w.getTrunk().equals("ette+0")
					|| w.getTrunk().equals("ettepoole+0")
					|| w.getTrunk().equals("juurde+0")
					|| w.getTrunk().equals("kaugele+0")
					|| w.getTrunk().equals("koju+0")
					|| w.getTrunk().equals("kuhu+0")
					|| w.getTrunk().equals("kusagile+0")
					|| w.getTrunk().equals("kuskile+0")
					|| w.getTrunk().equals("kõikjale+0")
					|| w.getTrunk().equals("kõrvale+0")
					|| w.getTrunk().equals("ligi+0")
					|| w.getTrunk().equals("ligidale+0")
					|| w.getTrunk().equals("lähedale+0")
					|| w.getTrunk().equals("mujale+0")
					|| w.getTrunk().equals("paremale+0")
					|| w.getTrunk().equals("siia+0")
					|| w.getTrunk().equals("siiapoole+0")
					|| w.getTrunk().equals("sinna+0")
					|| w.getTrunk().equals("sinnapoole+0")
					|| w.getTrunk().equals("taamale+0")
					|| w.getTrunk().equals("taha+0")
					|| w.getTrunk().equals("tahapoole+0")
					|| w.getTrunk().equals("teisale+0")
					|| w.getTrunk().equals("tänna+0")
					|| w.getTrunk().equals("vasakule+0")
					|| w.getTrunk().equals("väljapoole+0")
					|| w.getTrunk().equals("üles+0")
					|| w.getTrunk().equals("ülespoole+0");
		}
		return result;
	}

}
